package com.xygz.orm;

import com.xiyuan.smartutils.Classes;
import com.xiyuan.smartutils.reflect.Unsafe;
import com.xygz.orm.exception.ORMException;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * ORM 加载器
 *
 * @author xiyuan-lgz 2023-11-11 @version v1.0.0 新建与整理
 */

@SuppressWarnings("unchecked")
class ORMLoader {
    private static final String PKG = ORM.class.getPackage().getName();
    private static final String LOC = ".internal.";
    private static ORMManager manager;
    
    private static void loadLibrary(String key) throws ORMException {
        // 到时候可以使用该类当做密码加密等信息
    }
    
    private static <M extends ORMManager> M loadManager(String key) throws ORMException {
        
        
        try {
            if (manager != null) return (M) manager;
            Class<?> clz = Classes.forName(PKG + LOC + "_ORMManager");
            List<Class<ORMManager>> ps = new ArrayList<>(1);
            if (ORMManager.class.isAssignableFrom(clz)) {
                ps.add((Class<ORMManager>) clz);
            }
            else {
                ps = Classes.getSubTypes(ORMManager.class, (c) -> !c.isInterface() && !Modifier.isAbstract(c.getModifiers()), PKG + LOC);
                if (ps.isEmpty()) {throw new ORMException("无法初始化ORM");}
            }
            Method method = ps.get(0).getDeclaredMethod("instanceManager", String.class);
            Unsafe.setAccessible(method, true);
            manager = (ORMManager) method.invoke(null, key);
            // 实例化并初始化
            return (M) manager;
        }
        catch (ORMException e) {
            throw e;
        }
        catch (Throwable e) {
            throw new ORMException(e.getMessage(), e);
        }
    }
    
    public static <M extends ORMManager> M init() throws ORMException {
        if (manager != null) {return (M) manager;}
//        synchronized (ORMManager.class) {
        try {
            Unsafe.init();
            if (manager != null) return (M) manager;
            // 字节码加密密钥
            String key = "";
            // 解析加密文件
            loadLibrary(key);
            // 加载实现类
            return loadManager(key);
        }
        catch (ORMException e) {
            throw e;
        }
        catch (Throwable e) {
            throw new ORMException("加载ORM失败！", e);
        }
//        }
    }
}
